unit unitSemaphoreLock;

interface

uses Windows;

function Lock(Name: PAnsiChar): THandle;
function UnLock(Handle: THandle): BOOL;
function SpinLock(Name: PAnsiChar): THandle;
function SpinUnLock(Handle: THandle): BOOL;

implementation

function Lock(Name: PAnsiChar): THandle;
begin
  Result := CreateSemaphoreA(nil, 1, 1, Name);
  if DWORD(Result) > 0 then
    WaitForSingleObject(Result, INFINITE);
end;

function UnLock(Handle: THandle): BOOL;
begin
  if DWORD(Handle) > 0 then
    ReleaseSemaphore(Handle, 1, nil);
  // CloseHandle(Handle);
  // or CloseHandle(Handle); ?
end;

function SpinLock(Name: PAnsiChar): THandle;
begin
  SetLastError(0);
  Result := CreateMutexA(nil, false, Name);
  if GetLastError = ERROR_ALREADY_EXISTS then
  begin
    SpinUnLock(Result);
    Result := 0;
  end;
end;

function SpinUnLock(Handle: THandle): BOOL;
begin
  Result := ReleaseMutex(Handle);
  CloseHandle(Handle);
end;

end.
